home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471323519
Publication Date: 11/01/98

Search this book:
 
Previous Table of Contents Next


This is the sort of error that may occur when the compiled program runs. The user may have deleted a key data file, the file may be mounted remotely on a network that is down, or the file may be on a floppy disk that is not inserted in the floppy drive.

Because the parameter in these cases might sometimes be valid, the routine should not merely stop. Instead, it should raise an error and let the calling routine try to figure out what the problem is. In this example, the calling routine might display a warning and let the user decide whether to retry the file operation or cancel it. If the file is on a missing floppy disk, the user may be able to insert the disk. Then the program could retry the operation and continue successfully.

A routine should never quietly ignore an invalid parameter and take some reasonable default action. Invalid parameters indicate either a problem in the code (the calling routine has a bug) or a problem in the environment (a file is missing). In either case, you should bring the problem to someone’s attention so it can be fixed. Highlight the problem instead of hiding it.

Use Tight Restrictions

Restrictions make bugs obvious. When a bug violates the restrictions, it is easy to tell there is a problem.

To catch as many bugs as possible, use the tightest restrictions that are acceptable. Later, if there is a proven need for looser restrictions, you can loosen them.

For instance, suppose the PlotArray subroutine shown in the following code displays a bar graph of data values on a form’s background. PlotArray requires that the number of values it is passed be between 10 and 20.

That restriction was chosen somewhat arbitrarily. A program may want to display fewer values, but the result would look a bit empty. A program may also want to display more values, but the form would look crowded. Requiring between 10 and 20 values is reasonable lacking any other information. If it later becomes necessary for the program to display a graph of 50 values, the restriction can be loosened. Until then, the restriction remains tight to guard against obviously invalid values like 2 or 10,000.

Private Sub PlotValues(values() As Single)
Dim num_values As Integer
Dim min_value As Single
Dim max_value As Single
Dim i As Integer

    ‘ Verify that there are between 10 and 20 values.
    num_values = UBound(values) - LBound(values) + 1
    If num_values < 10 Or num_values > 20 Then Stop

    ‘ Find the biggest and smallest values.
    min_value = values(LBound(values))
    max_value = min_value
    For i = LBound(values) + 1 To UBound(values)
        If min_value > values(i) Then min_value = values(i)
        If max_value < values(i) Then max_value = values(i)
    Next i

    ‘ Set the form’s Scale properties.
    ScaleLeft = LBound(values) - 1
    ScaleWidth = UBound(values) - ScaleLeft
    ScaleTop = max_value
    ScaleHeight = min_value - ScaleTop

    ‘ Plot the values.
    For i = LBound(values) To UBound(values)
        FillStyle = (i Mod 7) + 1
        Line (i - 1, min_value)-(i, values(i)), , B
    Next i
End Sub

To make as many bugs as possible instantly visible, start with tight restrictions and loosen them only when absolutely necessary.

Use LBound and UBound

Chapter 4, “Constants and Enums,” recommends that you use constants to define array bounds. For example, the following code uses a constant to declare an array and then initialize its elements to random values between 1 and 99.

Option Explicit

Private Const NUM_VALUES = 10
Private Values(1 To NUM_VALUES) As Integer

‘ Initialize the random values.
Private Sub Form_Load()
    InitializeValues
End Sub

‘ Initialize the Values array with random numbers
‘ between 1 and 99.
Private Sub InitializeValues()
Dim i As Integer

    Randomize
    For i = 1 To NUM_VALUES
        Values(i) = Int(99 * Rnd + 1)
    Next i
End Sub

The constant NUM_VALUES makes this code easy to modify. If you change NUM_VALUES to 100, you do not need to modify the InitializeValues subroutine. Because the routine uses the constant to determine the array’s upper bound, it will automatically use the new upper bound if you change it.

However, the InitializeValues routine does contain the hard-coded value 1 as the array’s lower bound. If you change the array’s lower bound to 0 or some other value, the subroutine will not work properly. You could create new FIRST_VALUE and LAST_VALUE constants giving the array’s bounds, but that would be needlessly complicated.

A better solution is to make subroutines like InitializeValues use LBound and UBound to determine the array’s bounds. Then no matter how you change the array’s bounds, the routine will function correctly. In fact, this routine will work even if the array is dynamically resized using the ReDim statement so it has bounds –100 and –75.

‘ Initialize the Values array with random numbers
‘ between 1 and 99.
Private Sub InitializeValues()
Dim i As Integer
    Randomize
    For i = LBound(Values) To UBound(Values)
        Values(i) = Int(99 * Rnd + 1)
    Next i
End Sub

Using this technique, only the code that actually declares the array needs to refer to constants or hard-coded values giving the array’s bounds. All other routines can use LBound and UBound to determine the array’s current bounds.

When you write routines like this one, carefully consider how the routine will react to typical and unusual upper and lower bounds. For example, how will the routine behave if the lower bound is 0 or 1? What if both bounds are negative? Can it handle the case when the upper and lower bounds are the same?

Notice also that UBound and LBound are undefined for arrays that have not been allocated. For example, the following code generates a subscript out of range error when it tries to determine LBound(Values) and UBound(Values).

Option Explicit

Private Const NUM_VALUES = 10
Private Values() As Integer

‘ Initialize the random values.
Private Sub Form_Load()
    InitializeValues
End Sub

‘ Initialize the Values array with random numbers
‘ between 1 and 99.
Private Sub InitializeValues()
Dim i As Integer

    Randomize
    For i = LBound(Values) To UBound(Values)
        Values(i) = Int(99 * Rnd + 1)
    Next i
End Sub


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.